﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace DataLayer
{
    public static class XmlEngine
    {
        #region ' Write '

        /// <summary>
        /// Serialize Stream from class object.
        /// </summary>
        /// <param name="stream">Stream to serialize to</param>
        /// <param name="obj">Object to be serialized</param>
        public static void Write<T>(Stream stream, T obj)
        {
            var s = new XmlSerializer(typeof(T));
            s.Serialize(stream, obj);
        }

        /// <summary>
        /// Serialize TextWriter from class object.
        /// </summary>
        /// <param name="twriter">TextWriter to serialize to</param>
        /// <param name="obj">Object to be serialized</param>
        public static void Write<T>(TextWriter twriter, T obj)
        {
            var s = new XmlSerializer(typeof(T));
            s.Serialize(twriter, obj);
        }

        /// <summary>
        /// Serialize XmlWriter from class object.
        /// </summary>
        /// <param name="xwrt">XmlWriter to serialize to</param>
        /// <param name="obj">Object to be serialized</param>
        public static void Write<T>(XmlWriter xwrt, T obj)
        {
            var s = new XmlSerializer(typeof(T));
            s.Serialize(xwrt, obj);
        }

        /// <summary>
        /// Serialize and save class object to file trough StreamWriter.
        /// </summary>
        /// <param name="filename">File name</param>
        /// <param name="obj">Object to be serialized</param>
        public static void Write<T>(string filename, T obj)
        {
            var swrit = new StreamWriter(filename);
            Write(swrit, obj);
            swrit.Close();
        }

        /// <summary>
        /// Serialize and save class object to file trough StreamWriter.
        /// </summary>
        /// <param name="filename">File name</param>
        /// <param name="obj">Object to be serialized</param>
        public static void Write<T>(string filename, T obj, Encoding enc)
        {
            var swrit = new StreamWriter(filename, false, enc);
            Write(swrit, obj);
            swrit.Close();
        }

        /// <summary>
        /// Serialize and save class object to file trough StreamWriter.
        /// </summary>
        /// <param name="filename">File name</param>
        /// <param name="obj">Object to be serialized</param>
        public static void AppendWrite<T>(string filename, T obj)
        {
            var swrit = new StreamWriter(filename, true);
            Write(swrit, obj);
            swrit.Close();
        }

        /// <summary>
        /// Serialize to xml sring from class object.
        /// </summary>
        /// <param name="obj">Object to be serialized</param>
        /// <returns>string</returns>
        public static string Write<T>(T obj)
        {
            var memoryStream = new MemoryStream();

            var xs = new XmlSerializer(typeof(T));
            var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

            xs.Serialize(xmlTextWriter, obj);
            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;

            return null;// ConvertFormat.UTF8ByteArrayToString(memoryStream.ToArray()).Substring(1);
        }

        #endregion

        #region ' Read '

        /// <summary>
        /// Desirealize xml string to class object
        /// </summary>
        /// <param name="pXmlizedString">Xml string to read</param>
        /// <returns>class object</returns>
        public static T Read<T>(string pXmlizedString)
        {
            var xs = new XmlSerializer(typeof(T));
            var memoryStream = new MemoryStream();//ConvertFormat.StringToUTF8ByteArray(pXmlizedString));
            var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            return (T)xs.Deserialize(memoryStream);
        }

        /// <summary>
        /// Desirealize xml file to class object
        /// </summary>
        /// <param name="fname">File name</param>
        /// <returns>class object</returns>
        public static T ReadFromFile<T>(string fname)
        {
            T TC;
            using (var t = new StreamReader(fname))
            {
                TC = Read<T>(t);
            }

            return TC;
        }

        /// <summary>
        /// Desirealize xml file to class object
        /// </summary>
        /// <param name="fname">File name</param>
        /// <returns>class object</returns>
        public static T ReadFromFile<T>(string fname, Encoding enc)
        {
            T tc;
            using (var t = new StreamReader(fname, enc))
            {
                tc = Read<T>(t);
            }

            return tc;
        }

        /// <summary>
        /// Desirealize Stream to class object
        /// </summary>
        /// <param name="str">Stream to deserialize</param>
        /// <returns>class object</returns>
        public static T Read<T>(Stream str)
        {
            var s = new XmlSerializer(typeof(T));
            return (T)s.Deserialize(str);
        }

        /// <summary>
        /// Desirealize TestReader to class object
        /// </summary>
        /// <param name="trid">TextReader to deserialize</param>
        /// <returns>class object</returns>
        public static T Read<T>(TextReader trid)
        {
            var s = new XmlSerializer(typeof(T));
            return (T)s.Deserialize(trid);
        }

        /// <summary>
        /// Desirealize XmlReader to class object
        /// </summary>
        /// <param name="xrid">XmlReader to deserialize</param>
        /// <returns>class object</returns>
        public static T Read<T>(XmlReader xrid)
        {
            var s = new XmlSerializer(typeof(T));
            return (T)s.Deserialize(xrid);
        }

        #endregion
    }
}
